/**
 * 项目名：五位一体化工安全信息平台
 * 日期：    2019-11-25 11:03:30
 * Copyright (c) 2015- joysuch-版权所有
 */

package com.joysuch.wwyt.core.service.impl;

import javax.transaction.Transactional;

import com.google.common.collect.Lists;
import com.joysuch.wwyt.bp.bean.BpEmergencyTrainingDrillListBean;
import com.joysuch.wwyt.bp.entity.BpEmergencyTrainingDrill;
import com.joysuch.wwyt.bp.entity.dsl.QBpEmergencyTrainingDrill;
import com.joysuch.wwyt.bp.enums.DataStateTypes;
import com.joysuch.wwyt.core.bean.BaseAttachmentBean;
import com.joysuch.wwyt.core.bean.BaseTypeGroupItemBean;
import com.joysuch.wwyt.core.bean.BaseTypeGroupItemSearchBean;
import com.joysuch.wwyt.core.common.util.PageDataUtils;
import com.joysuch.wwyt.core.common.util.PinYinUtils;
import com.joysuch.wwyt.core.common.util.SimpleDateFormatCache;
import com.joysuch.wwyt.core.entity.BaseTypeGroup;
import com.joysuch.wwyt.core.entity.BaseTypeGroupItem;
import com.joysuch.wwyt.core.entity.dsl.QBaseTypeGroupItem;
import com.joysuch.wwyt.core.repository.BaseTypeGroupDao;
import com.joysuch.wwyt.core.repository.BaseTypeGroupItemDao;
import com.joysuch.wwyt.core.service.BaseTypeGroupItemService;
import com.joysuch.wwyt.core.service.BizCodeGeneratorFacade;
import com.querydsl.core.types.ExpressionUtils;
import com.querydsl.core.types.Predicate;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.ss.formula.functions.T;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.data.domain.*;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.text.ParseException;
import java.util.*;
import java.util.stream.Collectors;

@Service
@Transactional
public class BaseTypeGroupItemServiceImpl implements BaseTypeGroupItemService {

    private static final Logger logger = LoggerFactory.getLogger(BaseTypeGroupItemServiceImpl.class);

    @Autowired
    private BaseTypeGroupItemDao dao;
    @Autowired
    private BizCodeGeneratorFacade bizCodeGeneratorFacade;

    @Autowired
    private BaseTypeGroupDao baseTypeGroupDao;


    @Override
    public void add(BaseTypeGroupItem entity) throws Exception {
        dao.save(entity);
    }

    @Override
    public void update(BaseTypeGroupItem entity) throws Exception {
        BaseTypeGroupItem content = dao.findById(entity.getId()).get();
        if (content != null) {
            // TODO set nessessary properties
            dao.save(entity);
        }
    }

    @Override
    public Page<BaseTypeGroupItem> findByPage(Pageable page) {
        return dao.findAll(page);
    }

    @Override
    public void delete(Long id) {
        dao.deleteById(id);
    }

    @Override
    public BaseTypeGroupItem findById(Long id) {
        return dao.findById(id).get();
    }

    @Override
    public String findNameById(Long id) {
        if (id == null) {
            return null;
        }
        try {
            return findById(id).getName();
        } catch (Exception e) {
            logger.error("查询字典项#" + id + "出错", e);
        }
        return null;
    }


    /**
     * 增加数据字典
     *
     * @param bean
     * @return
     */
    @Override
    public BaseTypeGroupItem addItem(BaseTypeGroupItemBean bean) {
        BaseTypeGroupItem item = new BaseTypeGroupItem();
        BeanUtils.copyProperties(bean, item);
        //拼接code
        BaseTypeGroup group = baseTypeGroupDao.findById(bean.getTypeGroupId()).orElseThrow(() -> new IllegalArgumentException("字典类型不存在"));
        String abbrev = group.getCode();
        String itemCode = PinYinUtils.getHanziInitials(bean.getName());
        //如果字典名称无法解析成汉语拼音则后缀用字段名称
        if (StringUtils.isNotBlank(itemCode)) {
            abbrev = abbrev + "_" + PinYinUtils.getHanziInitials(bean.getName());
        } else {
            abbrev = abbrev + "_" + bean.getName();
        }
        //字典名称如果已存在则在后面添加数字
        List<BaseTypeGroupItem> giList = dao.getListByCodeLike(abbrev);
        if (!CollectionUtils.isEmpty(giList)) {
            abbrev = abbrev + (giList.size() + 1);
        }
        item.setCode(abbrev);
        item.setState(DataStateTypes.EFFECTIVE.getState());
        BaseTypeGroupItem save = dao.save(item);
        checkItem(save);
        return save;
    }

    /**
     * 修改数据字典
     *
     * @param bean
     * @return
     */
    @Override
    public BaseTypeGroupItem updateItem(BaseTypeGroupItemBean bean) {
        BaseTypeGroupItem item = dao.findById(bean.getId()).orElseThrow(() -> new IllegalArgumentException("数据字典不存在"));
        item.setName(bean.getName());
        item.setShowOrder(bean.getShowOrder());
        item.setTypeGroupId(bean.getTypeGroupId());
        BaseTypeGroupItem save = dao.save(item);
        checkItem(save);
        return save;
    }

    private void checkItem(BaseTypeGroupItem item) {
        List<BaseTypeGroupItem> iList = dao.findByNameAndTypeGroupId(item.getName(), item.getTypeGroupId());
        if (iList.size() > 1) {
            throw new IllegalArgumentException("字典名称已存在");
        }
    }

    /**
     * 删除数据字典
     *
     * @param id
     */
    @Override
    public void deleteItem(Long id) {
        BaseTypeGroupItem item = dao.findById(id).orElseThrow(() -> new IllegalArgumentException("数据字典不存在"));
        item.setState(DataStateTypes.UN_EFFECTIVE.getState());
        dao.save(item);
    }

    /**
     * 查看数据字典
     *
     * @param id
     * @return
     */
    @Override
    public BaseTypeGroupItemBean findItemById(Long id) {
        BaseTypeGroupItem item = dao.findById(id).orElseThrow(() -> new IllegalArgumentException("数据字典不存在"));
        BaseTypeGroupItemBean bean = new BaseTypeGroupItemBean();
        BeanUtils.copyProperties(item, bean);
        if (item.getTypeGroupId() != null) {
            bean.setTypeGroupName(baseTypeGroupDao.findById(item.getTypeGroupId()).get().getName());
        }
        return bean;
    }

    /**
     * 分页查询
     *
     * @param page
     * @param condition
     * @return
     * @throws ParseException
     */
    @Override
    public Page<BaseTypeGroupItemBean> pageItem(Pageable page, BaseTypeGroupItemSearchBean condition) throws ParseException {
        page = PageDataUtils.addOrderByAsc(page, "showOrder");
        page = PageDataUtils.addOrderByDesc(page, "id");
        Predicate predicate = prepareListSearchCondition(condition);
        Page<BaseTypeGroupItem> data = predicate == null ? dao.findAll(page) : dao.findAll(predicate, page);
        return PageDataUtils.convertPageData(data,
                new PageDataUtils.PageDataConvert<BaseTypeGroupItemBean, BaseTypeGroupItem>() {
                    @Override
                    public BaseTypeGroupItemBean convert(BaseTypeGroupItem f) {
                        BaseTypeGroupItemBean bean = new BaseTypeGroupItemBean();
                        BeanUtils.copyProperties(f, bean);
                        if (f.getTypeGroupId() != null) {
                            Optional<BaseTypeGroup> otg = baseTypeGroupDao.findById(f.getTypeGroupId());
                            if (otg.isPresent()) {
                                bean.setTypeGroupName(baseTypeGroupDao.findById(f.getTypeGroupId()).get().getName());
                            }
                        }
                        return bean;
                    }
                });
    }

    public List<BaseTypeGroupItemBean> findAllByTypeName(String typeName)  {
        BaseTypeGroup typeGroup = baseTypeGroupDao.findByName(typeName);
        if (typeGroup == null) {
            return new ArrayList<>(0);
        }

        QBaseTypeGroupItem q = QBaseTypeGroupItem.baseTypeGroupItem;
        Predicate predicate = null;

        predicate = ExpressionUtils.and(predicate, q.typeGroupId.eq(typeGroup.getId()));
        predicate = ExpressionUtils.and(predicate, q.state.eq(DataStateTypes.EFFECTIVE.getState()).or(q.state.isNull()));

        Iterable<BaseTypeGroupItem> all = dao.findAll(predicate);
        List<BaseTypeGroupItemBean> list = Lists.newArrayList();
        all.forEach(f -> {
            BaseTypeGroupItemBean bean = new BaseTypeGroupItemBean();
            BeanUtils.copyProperties(f, bean);
            if (f.getTypeGroupId() != null) {
                Optional<BaseTypeGroup> otg = baseTypeGroupDao.findById(f.getTypeGroupId());
                if (otg.isPresent()) {
                    bean.setTypeGroupName(baseTypeGroupDao.findById(f.getTypeGroupId()).get().getName());
                }
            }

            if (bean.getShowOrder() == null) {
                bean.setShowOrder(0);
            }
            list.add(bean);
        });
        List<BaseTypeGroupItemBean> collect = list.stream().sorted(Comparator.comparing(BaseTypeGroupItemBean::getShowOrder)).collect(Collectors.toList());

        return collect;
    }

    /**
     * 批量增加数据字典
     *
     * @param list
     * @return
     */
    @Override
    public List<BaseTypeGroupItem> addListItem(List<BaseTypeGroupItemBean> list) {
        List<BaseTypeGroupItem> items = new ArrayList<>();
        if (!CollectionUtils.isEmpty(list)) {
            for (BaseTypeGroupItemBean bean : list) {
                BaseTypeGroupItem item = addItem(bean);
                if (item != null) {
                    items.add(item);
                }
            }
        }
        return items;
    }

    @Override
    public BaseTypeGroupItem findByGroupNameAndItemName(String groupName, String itemName) {
        BaseTypeGroup group = baseTypeGroupDao.findByName(groupName);
        if (group != null) {
            List<BaseTypeGroupItem> items = dao.findByNameAndTypeGroupId(itemName, group.getId());
            return items.isEmpty() ? null : items.get(0);
        }
        return null;
    }

    @Override
    public List<BaseTypeGroupItem> findByTypeGroupId(Long typeGroupId) {
        return dao.findByTypeGroupId(typeGroupId);
    }

    //构建查询条件
    private Predicate prepareListSearchCondition(BaseTypeGroupItemSearchBean condition) throws ParseException {
        QBaseTypeGroupItem q = QBaseTypeGroupItem.baseTypeGroupItem;
        Predicate predicate = null;
        if (StringUtils.isNotBlank(condition.getItemName())) {
            predicate = ExpressionUtils.and(predicate, q.name.like("%" + condition.getItemName() + "%"));
        }
        if (condition.getTypeId() != null) {
            predicate = ExpressionUtils.and(predicate, q.typeGroupId.eq(condition.getTypeId()));
        }
        predicate = ExpressionUtils.and(predicate, q.state.eq(DataStateTypes.EFFECTIVE.getState()).or(q.state.isNull()));
        return predicate;
    }

}
